/**
 **************************************************************************************************************************
 * 
 **************************************************************************************************************************
 * @file RBEffectDataContainer.h
 **************************************************************************************************************************/

#pragma once

#ifdef  HEADER_MSG
#pragma HEADER_MSG(RBEffectDataContainer.h)
#endif


/**************************************************************************************************************************
 * Includes
 **************************************************************************************************************************/
#include <RBMain/RBCommon.h>
#include <RBMain/RBTextureSampler.h>
#include <malloc.h>

/**************************************************************************************************************************
 * Forward declarations
 **************************************************************************************************************************/
class RBShaderResourceView;

#include "stb.h"

/**************************************************************************************************************************
 * Classes
 **************************************************************************************************************************/
class RBEffectDataContainer
{
public:
    typedef RBStringID Key;

     RBEffectDataContainer();
    ~RBEffectDataContainer();

     // Will copy effect data, but keep shader resource views
     RBEffectDataContainer(const RBEffectDataContainer& rhs);
     RBEffectDataContainer& operator=(const RBEffectDataContainer& rhs);

    template<class T> 
    T* AddEffectData(const Key& strName, uint32 uiCount)
    {
        uint32 size = 4+sizeof(T)*uiCount;
        void* pDataInMap = malloc(size);
		uint32* pCount = (uint32*)pDataInMap;
		*pCount = size;

		InsertData((char*)strName.c_str(), pDataInMap);

        return (T*) ((char*)pDataInMap+4);
    }

    template<class T> 
    T* AddEffectData(const Key& strName, const T* pData, uint32 uiCount)
    {
        void* pDataInMap = AddEffectData<T>(strName, uiCount);
        memcpy(pDataInMap, pData, sizeof(T)*uiCount);
        return (T*) pDataInMap;
    }

    template<class T> 
    bool get_effect_data(const Key& strName, T** pData, uint32* pCount) const
    {
        bool data_found = get_effect_data_blob(strName, (const void**)pData, pCount);
        if (!data_found)
        {
            return false;
        }
        *pCount /= sizeof(T);
        return true;
    }

    bool get_effect_data_blob(const Key& strName, const void** pData, uint32* size) const;

    void AddView(const Key& strName, RBShaderResourceView*);
    RBShaderResourceView* GetView(const Key& strName) const;

    RBTextureSampler& GetSampler(const Key& strName);
    RBTextureSampler* RetrieveSampler(const Key& strName) const;

    void Clear();

private:
	
	void InsertData(char* name, void* data);

private:
    stb_sdict* m_mData;
    stb_sdict* m_mViews;
    stb_sdict* m_mSamplers;
};
